NLLLoss ================= 负对数似然损失(Negative Log Likelihood Loss)。输入为对数概率 ``log_probs`` 与标签 ``labels``,按类别权重 ``weight`` 计算逐样本损失,再按 ``reduction_type`` 归约。 设 batch 大小为 :math:`N`,类别数为 :math:`C`。``log_probs`` 形状为 :math:`N \times C`, ``labels`` / 逐样本损失长度为 :math:`N`,``weight`` 长度为 :math:`C`。 对样本 :math:`i`: .. math:: \ell_i = -\mathrm{log\_probs}[i, y_i] \cdot \mathrm{weight}[y_i] 其中 :math:`y_i = \mathrm{labels}[i]`。同时: .. math:: W = \sum_{i=0}^{N-1} \mathrm{weight}[y_i],\quad L = \sum_{i=0}^{N-1} \ell_i **reduction_type** - ``0``:None,写出逐样本 :math:`\ell_i`,输出长度 :math:`N` - ``1``:Sum,``loss[0]`` 为 :math:`L` - ``2``:Mean,``loss[0]`` 为 :math:`L / W`;若 :math:`W = 0` 则写 0 ``total_weight`` 始终写回 :math:`W`。 输入: - **log_probs** - 对数概率地址,形状 ``[batch_size, class_num]`` - **labels** - 标签索引地址,形状 ``[batch_size]``,元素为 ``int`` - **weight** - 类别权重地址,形状 ``[class_num]`` - **params** - ``long long`` 参数数组,长度至少 3,布局见下 - **core_mask** - 核掩码(仅共享存储版本使用) **params 布局:** - ``[0]`` ``batch_size`` - batch 大小 :math:`N` - ``[1]`` ``class_num`` - 类别数 :math:`C` - ``[2]`` ``reduction_type`` - 归约方式,取值 ``{0,1,2}`` 输出: - **loss** - 损失地址;None 时长度 :math:`N`,Sum / Mean 时使用 ``loss[0]`` - **total_weight** - 权重和 :math:`W` 的地址 支持平台: ``FT78NE`` ``MT7004`` .. note:: - FT78NE 支持 int8、fp32 - MT7004 支持 fp16、fp32 - ``log_probs`` 应为已取对数的概率;``labels[i]`` 需满足 :math:`0 \le y_i < C` - 本 DSP 接口的 ``reduction_type`` 为 ``0/1/2``(None / Sum / Mean),与 schema ``Reduction`` 枚举数值不完全相同 **共享存储版本:** .. c:function:: void i8_nll_loss_s(const int8_t *log_probs, const int *labels, const int8_t *weight, int32_t *loss, int32_t *total_weight, long long *params, int core_mask) .. c:function:: void hp_nll_loss_s(const float16 *log_probs, const int *labels, const float16 *weight, float16 *loss, float16 *total_weight, long long *params, int core_mask) .. c:function:: void fp_nll_loss_s(const float *log_probs, const int *labels, const float *weight, float *loss, float *total_weight, long long *params, int core_mask) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 16 // MT7004 示例(共享存储多核,DDR 地址) void TestNllLossSMCFp32(int core_mask) { int core_id = get_core_id(); int logic_core_id = GetLogicCoreId(core_mask, core_id); int core_num = GetCoreNum(core_mask); float *log_probs = (float *)0x81000000; int *labels = (int *)0x82000000; float *weight = (float *)0x83000000; float *loss = (float *)0x84000000; float *total_weight = (float *)0x85000000; long long params[3]; params[0] = 16; // batch_size params[1] = 16; // class_num params[2] = 0; // reduction_type = None sys_bar(0, core_num); fp_nll_loss_s(log_probs, labels, weight, loss, total_weight, params, core_mask); } void main() { int core_mask = 0b1111; TestNllLossSMCFp32(core_mask); } **私有存储版本:** .. c:function:: void i8_nll_loss_p(const int8_t *log_probs, const int *labels, const int8_t *weight, int32_t *loss, int32_t *total_weight, long long *params) .. c:function:: void hp_nll_loss_p(const float16 *log_probs, const int *labels, const float16 *weight, float16 *loss, float16 *total_weight, long long *params) .. c:function:: void fp_nll_loss_p(const float *log_probs, const int *labels, const float *weight, float *loss, float *total_weight, long long *params) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 12 // MT7004 示例(私有存储单核,AM 地址) void TestNllLossAMFp32(void) { float *log_probs = (float *)0x10010000; int *labels = (int *)0x10020000; float *weight = (float *)0x10030000; float *loss = (float *)0x10040000; float *total_weight = (float *)0x10050000; long long params[3]; params[0] = 16; // batch_size params[1] = 16; // class_num params[2] = 0; // reduction_type = None fp_nll_loss_p(log_probs, labels, weight, loss, total_weight, params); } void main() { TestNllLossAMFp32(); }